/*
 * @Author: liujieqiang 501920078@qq.com
 * @Date: 2022-08-23 10:09:20
 * @LastEditors: liujieqiang 501920078@qq.com
 * @LastEditTime: 2022-08-23 13:36:17
 * @FilePath: \vite复制配置文件插件\src\index.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import fs from 'fs-extra';
import path from 'path';
import externalGlobals from 'rollup-plugin-external-globals';
import { HtmlTagDescriptor, normalizePath, Plugin, UserConfig } from 'vite';

interface VitePluginOptions {
  moduleName?: string;
  outFileName?: string;
}

function getStr(str: string, start: string, end: string) {
  let res = str.match(new RegExp(`${start}(.*?)${end}`));
  return res ? res[1] : null
}

export default function vitePluginCopyConfig(options: VitePluginOptions = {}): Plugin {
  const {
    //使用模块的名称，必须以@开头，路径为src, import settings from "@/config/defaultSettings"
    moduleName = '@/config/defaultSettings',
    //导出的配置文件名称 可自定义
    outFileName = 'defaultSettings.js',
  } = options;
  let outDir = 'dist';
  let isBuild = false;
  let settingsFileText: string; //配置文件内容
  let settingGlobalName: string | undefined;//获取的全局windows挂载名称
  const settingsPath = path.join(`src${moduleName.replaceAll('@', '')}`);
  return {
    name: 'vite-plugin-copy-config',
    config(config, { command }) {
      isBuild = command === 'build';
      if (config.build?.outDir) {
        outDir = config.build.outDir;
      }
      const userConfig: UserConfig = {}
      if (isBuild) {
        try {
          //读取文件
          settingsFileText = fs.readFileSync(`${settingsPath}.ts`, 'utf8');
          //window.xxx 全局挂载的名称，注意配置文件中windows挂载要与这个同名
          settingGlobalName = getStr(settingsFileText, '\\(window as any\\)\\.', '=')?.trim();
        } catch (err) {
          console.log(err)
        }
        //如果找到挂载名称才进行rollup配置，否则直接不管打进包
        if (settingGlobalName) {
          userConfig.build = {
            rollupOptions: {
              external: [
                moduleName,
              ],
              plugins: [externalGlobals({ [moduleName]: settingGlobalName })]
            }
          };
        }
      }
      return userConfig
    },

    async closeBundle() {
      if (isBuild && settingGlobalName) {
        try {
          //替换ts
          const settingsTextJsText = settingsFileText.replaceAll('(window as any)', 'window')
          //读取文件
          fs.writeFileSync(`${settingsPath}.js`, settingsTextJsText)
          //复制文件
          await fs.copy(`${settingsPath}.js`, path.join(outDir, `./${outFileName}`));
          //删除文件
          fs.unlinkSync(`${settingsPath}.js`)
        } catch (err) {
          console.log(err)
        }
      }
    },

    transformIndexHtml() {
      const tags: HtmlTagDescriptor[] = [];
      if (isBuild && settingGlobalName) {
        tags.push({
          tag: 'script',
          attrs: {
            type: 'module',
            src: normalizePath(path.join('/', outFileName)),
          }
        });
      }
      return tags;
    }
  };
}
